package cate.game.friend.aid;

import cate.common.table.d.GDFriendAid;
import cate.common.util.GameResult;
import cate.game.db.mongo.kv.KvMongo;
import cate.game.role.Role;
import cate.game.role.bag.hero.Hero;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
@ToString
public class FriendAidSPO extends KvMongo {
    public Map<String, Map<Integer, ServerRoleAidHero>> serverAidHeros;

    @Override
    public String getKeyPrefix() {
        return KvMongo.KEY_FRIEND_AID;
    }

    public void eat(FriendAidSPO food){
        try {
            if(food == null || food.serverAidHeros == null) {
                log.info("FriendAidSPO 表示 没啥 可吃的数据 ... food.srvId={}", food.srvId);
            }
            food.serverAidHeros.forEach((k, v) -> {
                this.serverAidHeros.put(k, v);
            });
        } catch (Exception e) {
            log.error("", e);
        }
    }

    @Override
    public void initialize(){
        if (serverAidHeros == null) {
            serverAidHeros = new HashMap<>();
        }
    }

    public GameResult<Void> provide(int funcId, Role role, Hero hero) {
        GameResult<Void> r = new GameResult<>();
        if (role == null || hero == null) {
            return r.fail("数据异常");
        }
        synchronized (serverAidHeros) {
            serverAidHeros.putIfAbsent(role.getUid(), new HashMap<>());
        }
        final Map<Integer, ServerRoleAidHero> roleAidHeros = serverAidHeros.get(role.getUid());
        synchronized (roleAidHeros) {
            GDFriendAid.FuncAidData aidData = GDFriendAid.getAidData(funcId);
            ServerRoleAidHero aidHero = roleAidHeros.get(funcId);
            if (aidHero != null && aidHero.heroSize() >= aidData.getAidTimes()) {
                return r.fail("每天只可支援" + aidData.getAidTimes() + "次");
            }
            if (aidHero != null && aidHero.containsHero(hero.uid)) {
                return r.fail("您已经支援过该英雄");
            }
            if (aidHero == null) {
                aidHero = new ServerRoleAidHero(role);
                roleAidHeros.put(funcId, aidHero);
            }
            Hero cp = hero.copy();
            cp.initialize(role);
            cp.recordAttrPartWithRole(role.getGame().fight.getPlayBuildContext());
            cp.initialize(null);
            aidHero.add(cp);
        }
        return r;
    }

    public List<ServerRoleAidHero> getAidHeros(int funcId, Set<String> friends) {
        List<ServerRoleAidHero> list;
        synchronized (serverAidHeros) {
            list = serverAidHeros.entrySet().stream()
                    .filter(e -> friends.contains(e.getKey()))
                    .flatMap(e -> e.getValue().entrySet().stream())
                    .filter(e -> e.getKey() == funcId)
                    .map(Map.Entry::getValue)
                    .collect(Collectors.toList());
        }
        return list;
    }

    public ServerRoleAidHero getProvideHero(String roleUid, int funcId) {
        final Map<Integer, ServerRoleAidHero> roleAidHeros = serverAidHeros.get(roleUid);
        if (roleAidHeros == null) {
            return null;
        }
        return roleAidHeros.get(funcId);
    }

    public ServerRoleAidHero borrow(String roleUid, int funcId) {
        final Map<Integer, ServerRoleAidHero> roleAidHeros = serverAidHeros.get(roleUid);
        if (roleAidHeros != null) {
            return roleAidHeros.get(funcId);
        }
        return null;
    }

    public void onDaySpan() {
        serverAidHeros.clear();
    }
}
